#include "schema.h"
#include "globalDecl.h"

Schema :: Schema (char *_relName, char *_fName)
{
	int enter = -1;
	FILE *schemaFile = fopen(_fName, "r");
	m_name = _relName;
	if (schemaFile == NULL)
	{
		fclose (schemaFile);
	}
	else
	{
		char memorySpace[300];
		while (!feof(schemaFile)) 
		{
			fscanf (schemaFile, "%s", memorySpace);
			if (strncmp ("BEGIN", memorySpace, strlen ("BEGIN")) == 0) 
			{
				fscanf (schemaFile, "%s", memorySpace);
				if (strncmp (_relName, memorySpace, (strlen (memorySpace)-1)) == 0)
				{
					enter = 1;
					m_count = 0;
					int x = 0;
					while(x == 0)
					{
						fscanf (schemaFile, "%s", memorySpace);
						if(strncmp ("END", memorySpace, strlen ("END")) == 0)
						{ 
							x = 1;
						}
						else
						{
							NameType place;
							place.name = new char[strlen(memorySpace)+1];
							strcpy(place.name,memorySpace);
							//place.name = memorySpace;
							fscanf (schemaFile, "%s", memorySpace);
							
							if(strncmp ("Int",memorySpace, strlen ("Int")) == 0)
							{
								place.type = Int;
							}
							else if(strncmp ("String",memorySpace, strlen ("String")) == 0)
							{
								place.type = String;
							}
							else
							{
								place.type = Double;
							}
							place.index = m_count;
							m_count++;
							m_schemaCounts.insert( std::make_pair(place.name, place));
							//cout << place.name << " " << place.type << " " << place.index << endl;
						}
					}
				} 
			}
		}
		if(enter == 1)
		{
			m_NT = new NameType[m_count];
			map<std::string,NameType>::iterator iter;
			for( iter = m_schemaCounts.begin(); iter != m_schemaCounts.end(); ++iter ) 
			{
				m_NT[iter->second.index].name = new char[strlen(iter->second.name)+1];
				strcpy(m_NT[iter->second.index].name,iter->second.name);
				m_NT[iter->second.index].type = iter->second.type;
				m_NT[iter->second.index].index = iter->second.index;
			}
		}
		else
		{
			cout << "Incorrect Schema name" << endl;
			abort();
		}
		fclose (schemaFile);
	}
}
Schema :: Schema (const Schema & _schema) 
{
	m_count = _schema.m_count;
	m_name = _schema.m_name;

	m_NT = new NameType[m_count];
	for (int i = 0; i < m_count; i++) {
		m_NT[i].name = new char[strlen(_schema.m_NT[i].name)+1];
		strcpy(m_NT[i].name,_schema.m_NT[i].name);
		m_NT[i].type = _schema.m_NT[i].type;
		m_NT[i].index = _schema.m_NT[i].index;
		m_schemaCounts.insert(make_pair(m_NT[i].name, m_NT[i]));
	}
}

Schema :: ~Schema ()
{
	for(int x = 0;x<m_count;x++)
	{
		delete [] m_NT[x].name;
	}

	//if(m_NT)
	//delete []m_NT;
	
	map<std::string,NameType>::iterator iter;
	/*for( iter = m_schemaCounts.begin(); iter != m_schemaCounts.end(); ++iter ) 
	{
		delete [] iter->second.name;
	}*/
	m_schemaCounts.clear();	
}

int Schema :: Find (char *_attName)
{
	int x = 0;
	map<std::string,NameType>::iterator iter;
	if((iter = m_schemaCounts.find(_attName)) != m_schemaCounts.end()) //makes sure it matches a tableName
	{
		x = 1; //found
	}
	return(x);
}
Type Schema :: GetType (char *_attName)
{
	Type gt;
	map<std::string,NameType>::iterator iter;
	if((iter = m_schemaCounts.find(_attName)) != m_schemaCounts.end()) //makes sure it matches a tableName
	{
		gt = iter->second.type;
	}
	return(gt);
}
Type Schema :: GetType(int _place)
{
		return(m_NT[_place].type);
}
void Schema :: GetName(char * &_name, int _place)
{
	_name = new char[strlen(m_NT[_place].name)+1];
	strcpy(_name,m_NT[_place].name);
}
int Schema :: GetPlace(char *_attName)
{
	int ret = -1;
	map<std::string,NameType>::iterator iter;
	if((iter = m_schemaCounts.find(_attName)) != m_schemaCounts.end())
	{
		ret = iter -> second.index;
	}
	return (ret);
}
void Schema :: Print()
{
	cout << m_name << endl;
	for(int x = 0;x<m_count;x++)
	{
		printf("%s\t|",m_NT[x].name);
	}
	cout<<endl;
}
void Schema :: PrintName()
{
	cout << m_name << endl; 
}
void Schema :: PrintLn(int _i)
{
	cout << m_NT[_i].name << " ";
	if(m_NT[_i].type == 0)
	{
		cout << "Int: ";
	}
	else if(m_NT[_i].type == 1)
	{
		cout << "Double: ";
	}
	else
	{
		cout << "String: ";
	}	
}

int Schema:: GetAttrCount()
{
	return m_count;
}
int Schema:: GetLength(int _place)
{
	return (strlen(m_NT[_place].name));
}
